package edu.indiana.d2i.vmm.policy;

import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import edu.indiana.d2i.vmm.cloud.CloudInstanceInfo;
import edu.indiana.d2i.vmm.cloud.CloudProvider;
import edu.indiana.d2i.vmm.cloud.CloudVMRequest;
import edu.indiana.d2i.vmm.job.SigiriHTRCJobRequest;
import edu.indiana.d2i.vmm.vm.BasicHTRCVMController;
import edu.indiana.extreme.sigiri.JobInfoBean;

public class ShortRunVMMgrPolicy implements VMManagementPolicy {
	private final CloudProvider provider;
	private ConstraintsManager imageState;

	private static final Log logger = LogFactory
			.getLog(ShortRunVMMgrPolicy.class);

	public ShortRunVMMgrPolicy(ConstraintsManager imageMgr,
			CloudProvider provider) {
		this.provider = provider;
		this.imageState = imageMgr;
	}
	
	@Override
	// bottle neck!!! need to be changed!!!
	public synchronized BasicHTRCVMController allocateVMs(JobInfoBean jobInfo)
			throws Exception {
		BasicHTRCVMController vmController = null;
		String imageID = null;
		SigiriHTRCJobRequest jobRequest = null;
		try {
			// get user id, requesting resources
			jobRequest = SigiriHTRCJobRequest.parseFromXML(jobInfo
					.getJobDescription());

			// check if resources are available (i.e. software - 'ImageSoftware'
			// table, #resource - 'Instance' table)
			imageID = imageState.requestImage(jobRequest.softwareFrameWork,
					jobRequest.instanceNum);
			if (imageID != null) {
				List<CloudInstanceInfo> vms = provider
						.requestVMs(new CloudVMRequest(imageID,
								jobRequest.imageType, jobRequest.instanceNum));
				if (vms != null) {
					vmController = new BasicHTRCVMController(this,
							jobRequest.softwareFrameWork, vms);
				} else {
					imageState.releaseImage(jobRequest.softwareFrameWork,
							jobRequest.instanceNum);
					logger.info("No VM is allocated, revoke Image " + imageID + " status");
				}
			}
		} catch (Exception e) {
			logger.error(e);
			if (imageID != null) {
				logger.error("revoke Image " + imageID + " status");
				imageState.releaseImage(jobRequest.softwareFrameWork,
						jobRequest.instanceNum);
			}
			throw new Exception(e);
		}
		return vmController;
	}

	@Override
	public synchronized void releaseVMs(BasicHTRCVMController vmController) throws Exception {
		imageState.releaseImage(vmController.getSoftwareFrameworkName(),
				vmController.getVMInfo().size());
		provider.shutdownVMs(vmController.getVMInfo());
		logger.info("Shutdown VMs");
	}
}
